package controllers

import (
	"fmt"
	"fox/common"
	"fox/enum/code"
	"fox/enum/fields"
	"fox/models"
	"fox/repositories"
	request2 "fox/request"
	response2 "fox/response"
	"fox/validators"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"net/http"
	"strconv"
)

type UserController struct {
	repository *repositories.UserRepository
}

func NewUserController() (userController *UserController) {

	return &UserController{repository: repositories.NewUserRepository()}

}

func (controller *UserController) Login(c *gin.Context) {

	c.JSON(http.StatusOK, gin.H{
		"message":            "/user/login",
		"reponsetoryMessage": controller.repository.Login(c),
	})
	return
}

func (controller *UserController) SaveUser(c *gin.Context) {
	var (
		saveUser     *request2.SaveUser
		user         *models.User
		passwordByte []byte
		id           int64
		err          error
	)

	saveUser = &request2.SaveUser{}
	if err = c.ShouldBind(&saveUser); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, validators.Translate(err), ""))
		return
	}

	if passwordByte, err = bcrypt.GenerateFromPassword([]byte(saveUser.Password), bcrypt.MinCost); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, "密码加密失败:"+err.Error(), ""))
		return
	}
	user = &models.User{
		NickName:   saveUser.NickName,
		UserName:   saveUser.UserName,
		Password:   string(passwordByte),
		CreateTime: common.DateTimeNowFormat(),
		UpdateTime: common.DateTimeNowFormat(),
		Status:     fields.StatusOk,
	}

	if id, err = controller.repository.InsertUser(user); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, code.QueryErrorStr, ""))
		return
	}

	c.JSON(http.StatusOK, response2.Response(code.Success, code.SuccessStr, id))
	return
}

func (controller *UserController) GetUser(c *gin.Context) {
	var (
		idStr string
		idInt int
		user  *models.User
		err   error
	)

	idStr = c.Query("id")
	if idStr == "" {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, code.ParameterErrorStr, ""))
		return
	}
	if idInt, err = strconv.Atoi(idStr); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, err.Error(), ""))
		return
	}
	if user, err = controller.repository.SelectUserById(c, int64(idInt)); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, err.Error(), ""))
		return
	}

	if user, err = controller.repository.SelectUserById(c, int64(idInt)); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, err.Error(), ""))
		return
	}

	//TODO 在response里面将信息放入到log协程里面

	fmt.Println("sql:")
	fmt.Println(c.Get("sql"))
	c.JSON(http.StatusOK, response2.Response(code.Success, code.SuccessStr, user))
	return

}

func (controller *UserController) DeleteUser(c *gin.Context) {
	var (
		idStr string
		idInt int
		err   error
	)

	idStr = c.Query("id")
	if idStr == "" {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, code.ParameterErrorStr, ""))
		return
	}

	if idInt, err = strconv.Atoi(idStr); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, err.Error(), ""))
		return
	}

	if err = controller.repository.DeleteUserById(int64(idInt)); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, err.Error(), ""))
		return
	}

	c.JSON(http.StatusOK, response2.Response(code.Success, "删除成功", ""))
	return
}

func (controller *UserController) UpdateUser(c *gin.Context) {
	var (
		updateUser *request2.UpdateUser
		user       *models.User
		userNew    *models.User
		err        error
	)

	updateUser = &request2.UpdateUser{}
	if err = c.ShouldBind(&updateUser); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, validators.Translate(err), ""))
		return
	}

	user = &models.User{
		ID: updateUser.ID,
	}
	if len(updateUser.NickName) > 0 {
		user.NickName = updateUser.NickName
	}
	if len(updateUser.Avatar) > 0 {
		user.Avatar = updateUser.Avatar
	}
	if len(updateUser.Email) > 0 {
		user.Email = updateUser.Email
	}
	if len(updateUser.Password) > 0 {
		user.Password = updateUser.Password
	}
	if len(updateUser.Mobile) > 0 {
		user.Mobile = updateUser.Mobile
	}
	if updateUser.Status != fields.StatusOk && updateUser.Status != fields.StatusNo {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, "status有误", ""))
		return
	}
	user.Status = updateUser.Status

	if userNew, err = controller.repository.UpdateUserById(user); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, err.Error(), ""))
		return
	}

	c.JSON(http.StatusOK, response2.Response(code.Success, code.SuccessStr, userNew))
	return
}

func (controller *UserController) GetUsers(c *gin.Context) {
	var (
		user     *request2.User
		userName string
		users    *response2.Result
		ok       bool
		err      error
	)

	user = &request2.User{}
	if user.Page, err = strconv.Atoi(c.DefaultQuery("page", "1")); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, err.Error(), ""))
		return
	}
	if user.Size, err = strconv.Atoi(c.DefaultQuery("size", "10")); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, err.Error(), ""))
		return
	}
	user.Sort = c.DefaultQuery("sort", fields.DESC)
	if user.Sort != fields.DESC && user.Sort != fields.ASC {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, "排序有误", ""))
		return
	}
	user.SortField = c.DefaultQuery("sortField", fields.CreateTime)
	if ok = request2.ValidateUserSortFile(user.SortField); ok != true {
		c.JSON(http.StatusOK, response2.Response(code.ParameterError, "排序参数有误", ""))
		return
	}
	userName = c.Query("userName")
	if userName != "" {
		user.UserName = userName
	}
	if users, err = controller.repository.SelectUsers(user); err != nil {
		c.JSON(http.StatusOK, response2.Response(code.QueryError, err.Error(), ""))
		return
	}
	c.JSON(http.StatusOK, response2.Response(code.Success, code.SuccessStr, users))
	return
}
